//
//  HomeControlFocusSelectView.swift
//  WatermarkCamera
//
//  Created by Python on 2024/7/24.
//

import UIKit
import RxRelay

class HomeControlFocusSelectView: BaseView {

    typealias Times = FocusScale.Times
    /// stackView
    private lazy var stackView: UIStackView = {
        let stackV = UIStackView()
        stackV.axis = .vertical
        stackV.spacing = spacing
        stackV.distribution = .fill
        stackV.alignment = .center
        return stackV
    }()
    
    private lazy var buttons: [FocusScaleButton] = []
    
    /// 当前选中的倍数
    private(set) var selectedScaleModel: FocusScale?
    
    let viewWidth: CGFloat
    
    let scaleModels: [FocusScale]
    
    var spacing: CGFloat = 30.0
    
    var itemWH: CGFloat {
        return viewWidth
    }

    
    let didSelectedFocusScale: PublishRelay<CGFloat> = .init()
    
    init(width: CGFloat, scaleModels: [FocusScale]) {
        self.viewWidth = width
        self.scaleModels = scaleModels
        super.init(frame: .zero)
    }
    
    public required convenience init() {
        fatalError()
    }
    
    
    // MARK: UI
    override func createUI() {
        super.createUI()
        backgroundColor = UIColor.clear
        // stackView
        addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        let buttonWH = itemWH
        // 添加按钮
        scaleModels.forEach { model in
            let button = FocusScaleButton()
            button.layer.cornerRadius = buttonWH * 0.5
            button.scaleModel = model
            stackView.insertArrangedSubview(button, at: 0)
            buttons.append(button)
            button.snp.makeConstraints { make in
                make.width.height.equalTo(buttonWH)
            }
            button.rx.tap.subscribe(onNext: {
                [weak self] in
                guard let self = self else { return }
                // 选中某个焦距倍数,不显示所有的倍数
                self.selected(scaleModel: model, isShowScales: false)
                // 回调
                self.didSelectedFocusScale.accept(model.scale)
            }).disposed(by: rx.disposeBag)
        }
    }

}

extension HomeControlFocusSelectView {
    
    
    /// 计算高度
    func fittedHeight() -> CGFloat {
        let count = scaleModels.count
        if count <= 0 {
            return 0.0
        }
        let height = itemWH * CGFloat(count) + CGFloat(count - 1) * spacing
        return height
    }
    
    func reloadData() {
        guard buttons.count == scaleModels.count else { return }
        for (index, button) in buttons.enumerated() {
            let scaleModel = scaleModels[index]
            button.scaleModel = scaleModel
        }
    }
    
    
    /// 选中某个焦距倍数
    /// - Parameters:
    ///   - scaleModel: 要选中的焦距倍数
    ///   - isShowScales: 是否显示所有焦距倍数选项的值
    private func selected(scaleModel: FocusScale?, isShowScales: Bool) {
        guard let scaleModel = scaleModel else { return }
        if scaleModel.isSelected { return }
        // 取消之前选中的倍数
        selectedScaleModel?.isSelected = false
        // 重置之前选中的焦距倍数值
        selectedScaleModel?.reset()
        // 选中当前的倍数
        scaleModel.isSelected = true
        if !isShowScales { // 如果不显示所有的焦距倍数选项的值(即仅显示当前选中的焦距倍数值)
            // 隐藏之前选中的焦距倍数值
            selectedScaleModel?.isShowScale = false
            // 显示当前选中的焦距倍数值
            scaleModel.isShowScale = true
        }
        // 记录当前选中的倍数
        selectedScaleModel = scaleModel
        // 刷新UI
        reloadData()
    }
    
    /// 设置焦距倍数
    /// - Parameters:
    ///   - scale: 焦距倍数
    ///   - isShowScales: 是否显示所有焦距选项的值
    func set(scale: CGFloat, isShowScales: Bool) {
        guard scaleModels.count >= 2,
              let minScale = scaleModels.first?.times.rawValue,
              let maxScale = scaleModels.last?.times.rawValue
        else { return }
        // 焦距倍数校准
        let _scale = min(max(scale, minScale), maxScale)
        // 所有可选的焦距倍数
        var scales = scaleModels.map { $0.times.rawValue }
        // 插入当前倍数,并排序
        scales.append(_scale)
        scales.sort()
        // 查找要设置的焦距倍数的索引位置
        guard let index = scales.firstIndex(of: _scale) else { return }
        // 要选中的焦距选项倍数
        let selectedScale: CGFloat
        if index == 0 { // 如果要设置的倍数为最低倍数
            selectedScale = scales.first ?? 0.0
        } else { // 如果要设置的倍数位于中间或者最高倍数
            // 位于当前倍数前面的倍数(即小于当前倍数)
            let preScale = scales[index - 1]
            // 位于当前倍数后面的倍数(即大于等于当前倍数)
            let nextScale = scales[index + 1]
            // 边界值(前面倍数和后面倍数的中间值，比如[2,10],则中间值为6)
            let threshold = (nextScale + preScale) * 0.5
            if _scale >= threshold { // 超过边界值,则选中后面的选项
                selectedScale = nextScale
            } else { // 低于边界值,则选中前面的选项
                selectedScale = preScale
            }
        }
        // 选中按钮
        let scaleModel = scaleModels.first { $0.times.rawValue == selectedScale }
        selected(scaleModel: scaleModel, isShowScales: isShowScales)
    }
}

